#ifndef JSONCONVERT_H
#define JSONCONVERT_H

#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
#include <QVariant>
#include <QRectF>
#include <QPainterPath>
#include <QBuffer>
#include <QPixmap>

enum ParamsType{
    Global,//全局
    Local,//本地
    Individual//个体
};

class JsonConvert{
public:

    static QString convertImage(const QImage& image){
        QByteArray byteArray;
        QBuffer buffer(&byteArray);
        image.save(&buffer); // 使用PNG格式保存QImage到QBuffer
        return QString::fromLatin1(byteArray.toBase64().data());
    }

    static QImage convertToImage(const QString& base64){
        QByteArray imageData = QByteArray::fromBase64(base64.toUtf8());
        QImage image;
        if(!image.loadFromData(imageData)){
            qWarning("Failed to load image from base64 data.");
        }
        return image;
    }

    static QString convertPixmap(const QPixmap& pixmap){
        return convertImage(pixmap.toImage());
    }

    static QPixmap convertToPixmap(const QString& base64){
        QByteArray imageData = QByteArray::fromBase64(base64.toUtf8());
        QPixmap pixmap;
        if(!pixmap.loadFromData(imageData)){
            qWarning("Failed to load pixmap from base64 data.");
        }
        return pixmap;
    }

    static QJsonObject convertPointF(const QPointF& point){
        QJsonObject obj;
        obj["x"] = point.x();
        obj["y"] = point.y();
        return obj;
    }

    static QPointF convertToPointF(const QJsonObject& obj){
        return QPointF(obj["x"].toDouble(), obj["y"].toDouble());
    }

    static QJsonObject convertRectF(const QRectF& rect){
        QJsonObject rectObj;
        rectObj["x"] = rect.x();
        rectObj["y"] = rect.y();
        rectObj["width"] = rect.width();
        rectObj["height"] = rect.height();
        return rectObj;
    }

    static QRectF convertToRectF(const QJsonObject& obj){
        return QRectF(obj["x"].toDouble(),
                obj["y"].toDouble(),
                obj["width"].toDouble(),
                obj["height"].toDouble());
    }

    static QJsonArray convertPainterPathList(const QList<QPainterPath> list){
        QJsonArray arr;
        for(QPainterPath path : list){
            arr.append(JsonConvert::convertPainterPath(path));
        }
        return arr;
    }

    static QJsonArray convertPainterPath(const QPainterPath& path){
        QJsonArray elementsArray;
        for (int i = 0; i < path.elementCount(); ++i) {
            QJsonObject elementObj;
            elementObj["type"] = static_cast<int>(path.elementAt(i).type);
            elementObj["x"] = path.elementAt(i).x;
            elementObj["y"] = path.elementAt(i).y;
            elementsArray.append(elementObj);
        }
        return elementsArray;
    }

    static QList<QPainterPath> convertToPainterPathList(const QJsonArray& elementsArray){
        QList<QPainterPath> list;
        for(const QJsonValue &val : elementsArray){
            list.append(JsonConvert::convertToPainterPath(val.toArray()));
        }
        return list;
    }

    static QPainterPath convertToPainterPath(const QJsonArray& elementsArray){
        QPainterPath path;
        for (const QJsonValue &val : elementsArray) {
            QJsonObject elementObj = val.toObject();
            QPainterPath::Element element;
            element.type = static_cast<QPainterPath::ElementType>(elementObj["type"].toInt());
            element.x = elementObj["x"].toDouble();
            element.y = elementObj["y"].toDouble();
            if(element.type == QPainterPath::ElementType::MoveToElement){
                path.moveTo(element.x, element.y);
            }else{
                path.lineTo(element.x, element.y);
            }
        }
        return path;
    }

    static QJsonObject convertMap(const QMap<QString, QVariant> map){
        QJsonObject obj;
        for (auto it = map.begin(); it != map.end(); ++it) {
            obj[it.key()] = variantToJsonValue(it.value());
        }
        return obj;
    }

    static QMap<QString, QVariant> convertToMap(const QJsonObject &obj){
        QMap<QString, QVariant> map;
        for (auto it = obj.begin(); it != obj.end(); ++it) {
            map[it.key()] = jsonValueToVariant(it.value());
        }
        return map;
    }

    static QJsonValue variantToJsonValue(const QVariant &variant) {
        QJsonValue jsonValue;
        if (variant.canConvert<QJsonObject>()) {
            jsonValue = QJsonValue::fromVariant(variant.toJsonObject());
        } else if (variant.canConvert<QJsonArray>()) {
            jsonValue = QJsonValue::fromVariant(variant.toJsonArray());
        } else {
            jsonValue = QJsonValue::fromVariant(variant.toString());
        }
        return jsonValue;
    }

    static QVariant jsonValueToVariant(const QJsonValue &jsonValue) {
        QVariant variant;
        if (jsonValue.isObject()) {
            variant = jsonValue.toObject().toVariantMap();
        } else if (jsonValue.isArray()) {
            variant = jsonValue.toArray().toVariantList();
        } else {
            variant = jsonValue.toString();
        }
        return variant;
    }

    virtual QJsonObject toJsonObj() const = 0;

    virtual void fromJsonObj(const QJsonObject &obj) = 0;
};

#endif // JSONCONVERT_H
